import {
  CheckCircleFilled,
  CloseCircleFilled,
  ExclamationCircleFilled,
  LoadingOutlined,
} from '@ant-design/icons';
import classNames from 'classnames';
import React, { useContext, useLayoutEffect, useMemo } from 'react';
import { YmRow } from 'ym-design';
import FormLayoutContext from '../Context/FormLayoutContext';
import NoStyleItemContext from '../Context/NoStyleItemContext';
import FormItemInput from '../FormItemInput';
import FormItemLabel from '../FormItemLabel';
import type { FormItemStatusContextProps } from '../context';
// import { FormItemInputContext } from '../context';
import { FormItemInputContext } from 'antd/es/form/context'; //使得 antd-Input能使用该Context
import useDebounce from '../hooks/useDebounce';
import type {
  ItemHolderProps,
  ValidateStatus,
} from '../interface/FormItemType';

const iconMap = {
  success: CheckCircleFilled,
  warning: ExclamationCircleFilled,
  error: CloseCircleFilled,
  validating: LoadingOutlined,
};

const ItemHolder: React.FC<ItemHolderProps> = (props) => {
  const {
    className,
    style,
    errors,
    warnings,
    validateStatus,
    meta,
    hasFeedback,
    hidden,
    children,
    fieldId,
    onSubItemMetaChange,
    label,
    required,
    colon,
    labelAlign,
    labelCol,
    tooltip,
    wrapperCol,
    extra,
    help,
  } = props;
  const { prefixCls } = useContext(FormLayoutContext);
  const itemPrefixCls = `${prefixCls}-item`;
  const debounceErrors = useDebounce(errors);
  const debounceWarnings = useDebounce(warnings);
  const hasHelp = help !== undefined && help !== null;
  const hasError = !!(hasHelp || errors.length || warnings.length);
  const [marginBottom, setMarginBottom] = React.useState<number | null>(null);

  useLayoutEffect(() => {
    if (hasError) {
      //有校验信息时
      setMarginBottom(24);
    }
  }, [hasError]);

  //没有校验时
  const onErrorVisibleChanged = (nextVisible: boolean) => {
    if (!nextVisible) {
      setMarginBottom(null);
    }
  };

  // ======================== Status ========================

  const mergedValidateStatus = useMemo<ValidateStatus>(() => {
    let tempStatus: ValidateStatus = '';
    if (validateStatus !== undefined) {
      tempStatus = validateStatus;
    } else if (meta.validating) {
      tempStatus = 'validating';
    } else if (debounceErrors.length) {
      tempStatus = 'error';
    } else if (debounceWarnings.length) {
      tempStatus = 'warning';
    } else if (meta.touched) {
      tempStatus = 'success';
    }
    return tempStatus;
  }, [validateStatus, debounceErrors, debounceWarnings, meta]);

  // Input要根据 FormItemInputContext.Provider 值 设置各种状态的样式
  const formItemStatusContext = useMemo<FormItemStatusContextProps>(() => {
    let feedbackIcon: React.ReactNode;
    if (hasFeedback) {
      const IconNode = mergedValidateStatus && iconMap[mergedValidateStatus];
      feedbackIcon = IconNode ? (
        <span
          className={classNames(
            `${itemPrefixCls}-feedback-icon`,
            `${itemPrefixCls}-feedback-icon-${mergedValidateStatus}`,
          )}
        >
          <IconNode />
        </span>
      ) : null;
    }

    return {
      status: mergedValidateStatus,
      hasFeedback,
      feedbackIcon,
      isFormItemInput: true,
    };
  }, [mergedValidateStatus, hasFeedback]);

  // ======================== Render ========================
  const itemClassName = {
    [`${itemPrefixCls}-with-help`]:
      hasHelp || debounceErrors.length || debounceWarnings.length,
    [`${className}`]: !!className,

    // Status
    [`${itemPrefixCls}-has-feedback`]: mergedValidateStatus && hasFeedback,
    [`${itemPrefixCls}-has-success`]: mergedValidateStatus === 'success',
    [`${itemPrefixCls}-has-warning`]: mergedValidateStatus === 'warning',
    [`${itemPrefixCls}-has-error`]: mergedValidateStatus === 'error',
    [`${itemPrefixCls}-is-validating`]: mergedValidateStatus === 'validating',
    [`${itemPrefixCls}-hidden`]: hidden,
  };

  return (
    <div className={classNames(itemPrefixCls, itemClassName)} style={style}>
      {/*  marginBottom:24px */}
      <YmRow className={`${itemPrefixCls}-row`}>
        {/* Label */}
        <FormItemLabel
          label={label}
          htmlFor={fieldId}
          required={required}
          colon={colon}
          labelAlign={labelAlign}
          labelCol={labelCol}
          tooltip={tooltip}
        />
        {/* Input Group */}
        <FormItemInput
          wrapperCol={wrapperCol}
          fieldId={fieldId}
          errors={debounceErrors}
          warnings={debounceWarnings}
          status={mergedValidateStatus}
          help={help}
          extra={extra}
          marginBottom={marginBottom}
          onErrorVisibleChanged={onErrorVisibleChanged}
        >
          <NoStyleItemContext.Provider value={onSubItemMetaChange}>
            <FormItemInputContext.Provider value={formItemStatusContext}>
              {children}
            </FormItemInputContext.Provider>
          </NoStyleItemContext.Provider>
        </FormItemInput>
      </YmRow>
      {!!marginBottom && (
        <div
          className={`${itemPrefixCls}-margin-offset`}
          style={{
            marginBottom: -marginBottom,
          }}
        />
      )}
    </div>
  );
};

export default ItemHolder;
